﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text.Json;
using System.Threading.Tasks;
using WebTest.Core.Entities.OrderAggregate;
using WebTest.Core.Interfaces;
using WebTest.Infrastructure.Data;
using WebTest.WebApi.Models;

namespace WebTest.WebApi.Controllers
{
    [Route("[controller]")]
    [ApiController]
    [Authorize]
    public class OrderApiController : ControllerBase
    {
        private readonly IOrderService orderService;
        private readonly IDistributedCache cache;
        private readonly OrderContext context;
        public OrderApiController(IOrderService orderService, OrderContext context,IDistributedCache cache)
        {
            this.orderService = orderService;
            this.context = context;
            this.cache = cache;
        }

        [HttpGet("GetOrder")]
        public async Task<IActionResult> GetOrderAsync()
        {
            var json = await cache.GetStringAsync("order");

            if (!string.IsNullOrWhiteSpace(json))
            {
                await cache.RefreshAsync("order");

                return Ok(JsonSerializer.Deserialize<Order>(json));
            }

            var order = await context.Set<Order>().FirstAsync();
            if (order == null)
                return BadRequest();

            await cache.SetStringAsync("order", JsonSerializer.Serialize(order), new DistributedCacheEntryOptions
            {
                SlidingExpiration = TimeSpan.FromMinutes(20)
            });

            return Ok(order);
        }
        [HttpGet("GetOrderList")]
        public async Task<IActionResult> GetOrderListAsync(GetOrderModel model)
        {
            var orders = await orderService.GetOrderListAsync(model.PageSize, model.PageIndex);
            return Ok(orders);
        }
        [HttpPut("UpdateOrderAddress")]
        public async Task<IActionResult> UpdateOrderAddress(UpdateOrderAddressModel model)
        {
            var order = await context.Set<Order>().FirstAsync();

            order.SetOrderAddress(model.Address);

            order = await orderService.UpdateOrderAsync(order);

            return Ok(order);
        }
        [HttpPost("AddOrderAndItem")]
        public async Task<IActionResult> AddOrderItemAsync(List<OrderItemModel> models)
        {
            var order = new Order();

            models.ForEach(item => order.AddOrderItem(new OrderItem(item.Name, item.Price, item.Amount)));

            await orderService.AddAsync(order);

            return Ok();
        }
        [HttpDelete("DeleteOrder")]
        public async Task<IActionResult> DeleteOrderAsync()
        {
            var order = await context.Set<Order>().FirstAsync();

            var orderItems = context.Set<OrderItem>().Where(x => EF.Property<Guid>(x, "OrderId") == order.Id);
            context.RemoveRange(orderItems);
            await context.SaveChangesAsync();

            await orderService.DeleteAsync(order);

            return Ok();
        }
    }
}
